package pt.fct.mpc.rfbul;

import java.util.List;

import pt.fct.mpc.rfbul.database.MapperDatabaseAdapter;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MapperActivity
	extends Activity
{
	private String TAG = "RFBUL Mapper";
	private static final String SSID_TO_LOOK_FOR = "eduroam";
//	private static final String SSID_TO_LOOK_FOR = "qwerty";
	
	private Context context;
	private EditText view_edit_profile;
	private Button view_button_start;
	private Button view_button_stop;
	
	private int[] view_table_items_ids = new int[] { 
		R.id.layout_mapper_text_top_left, R.id.layout_mapper_text_top_center,
		R.id.layout_mapper_text_top_right,
		R.id.layout_mapper_text_middle_left, 
		R.id.layout_mapper_text_middle_center, 
		R.id.layout_mapper_text_middle_right,
		R.id.layout_mapper_text_bottom_left, 
		R.id.layout_mapper_text_bottom_center,
		R.id.layout_mapper_text_bottom_right,
		R.id.layout_mapper_text_door
	}; 
	
	private String[] view_table_items_positions = new String[] {
		"TL", "TC", "TR", "ML", "MC", "MR", "BL", "BC", "BR", "D"
	};
	
	private ScanProfile scan_profile = null;
	protected boolean mapper_is_started = false;
	
	private OnClickListener listener_start_stop_button = 
		new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				switch (v.getId())
				{
					case R.id.layout_mapper_button_start:

						boolean undefined_profile = true;
						do
						{
							ScanProfile profile = getScanProfile();
							
							if (profile == null)
								break;
							
							scan_profile = profile;
							
//							Editable text = view_edit_profile.getText();
//							
//							if (text == null)
//								break;
//
//							String text_str = text.toString();
//							if ((text_str == null) || (text_str.length() == 0))
//								break;
							
							undefined_profile = false;
							
						} while (false);
						
						if (undefined_profile)
						{
							toastAlert("A profile must be specified");
							return;
						}
						
						enableTablePositions();
						
						view_button_stop.setVisibility(View.VISIBLE);
						view_button_start.setVisibility(View.GONE);
						
						mapper_is_started  = true;
						
						break;
						
					case R.id.layout_mapper_button_stop:
						disableTablePositions();
						view_button_start.setVisibility(View.VISIBLE);
						view_button_stop.setVisibility(View.GONE);
						
						mapper_is_started = false;
						break;
				}
			}
		};
	protected int mapper_scanning_item = -1;
		
	private OnClickListener listener_table_item =
		new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				
				int scanning_table_item = getTableItemFromID(v.getId());
				
				if (scanning_table_item < 0)
				{
					toastAlert("Unknown view id");
					return;
				}
				
				mapper_scanning_item = scanning_table_item;
				
				scanStart();
			}
		};
		
	protected List<ScanResult> scan_results = null;
	Handler handler = new Handler();
	
	private BroadcastReceiver receiver_results =
		new BroadcastReceiver()
		{
			@Override
			public void onReceive(Context context, Intent intent)
			{
				if (intent.getAction().equals(
					WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
				{
					scan_results = wifi_manager.getScanResults();
					
					if ((progress_dialog != null) 
						&& (progress_dialog.isShowing()))
					{
						progress_dialog.dismiss();
					}
					
					handler.post(
						new Runnable()
						{
							@Override
							public void run()
							{
								doScanResultsHandling();
							}
						});
				}				
			}
		};
	
	private int table_item_disabled_color;
	private EditText view_edit_building;
	private EditText view_edit_floor;
	private EditText view_edit_wing;
	private EditText view_edit_room;
	private WifiManager wifi_manager;
	private ProgressDialog progress_dialog;
	private boolean mapper_is_scanning = false;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.rfbul_mapper);
		
		this.context = getApplicationContext();
		
//		this.view_edit_profile = 
//			(EditText) findViewById(R.id.layout_mapper_edit_profile);
		
		this.view_edit_building =
			(EditText) findViewById(R.id.layout_mapper_edit_building);
		this.view_edit_floor =
			(EditText) findViewById(R.id.layout_mapper_edit_floor);
		this.view_edit_wing =
			(EditText) findViewById(R.id.layout_mapper_edit_wing);
		this.view_edit_room =
			(EditText) findViewById(R.id.layout_mapper_edit_room);
		
		this.view_button_start =
			(Button) findViewById(R.id.layout_mapper_button_start);
		this.view_button_stop =
			(Button) findViewById(R.id.layout_mapper_button_stop);
		
		this.view_button_start.setOnClickListener(listener_start_stop_button);
		this.view_button_stop.setOnClickListener(listener_start_stop_button);
		
		
		// WIFI Manager
		
		this.wifi_manager = 
			(WifiManager) getSystemService(Context.WIFI_SERVICE);
        
        if (!wifi_manager.isWifiEnabled())
        {
        	if (wifi_manager.getWifiState() != WifiManager.WIFI_STATE_ENABLING)
        		wifi_manager.setWifiEnabled(true);
        }

        wifi_manager.createWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, TAG);
	}

	protected void scanStart()
	{
		if (mapper_is_scanning)
		{
			toastAlert("Already scanning.");
			return;
		}
		
		if (this.mapper_scanning_item < 0)
		{
			toastAlert("Undefined scanning item. We are not supposed to scan.");
			return;
		}
		
        registerReceiver(receiver_results, 
        	new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
		
		int view_id = view_table_items_ids[this.mapper_scanning_item];
		TextView table_item_view = 
			(TextView) findViewById(view_id);
		if (table_item_view == null)
		{
			toastAlert("unable to find position view");
			return;
		}
		
		table_item_view.setTextColor(
			getResources().getColor(R.color.mapper_cell_scanning));
		

		this.progress_dialog = new ProgressDialog(this);
        this.progress_dialog.setMessage("Scanning...");
        this.progress_dialog.show();
        
        this.mapper_is_scanning = true;
        
        wifi_manager.startScan();
	}

	protected int getTableItemFromID(int id)
	{
		int item_pos = -1;
		
		for (int i = 0; i < view_table_items_ids.length; i ++)
		{
			if (view_table_items_ids[i] == id)
			{
				item_pos = i;
				break;
			}
		}
		return item_pos;
	}

	// This is some awful code. My apologies.
	protected ScanProfile getScanProfile()
	{
		Editable editable;
		
		editable = view_edit_building.getText();
		if (editable == null)
			return null;
		
		String building = editable.toString();
		
		editable = view_edit_floor.getText();
		if (editable == null)
			return null;
		
		String floor = editable.toString();
		
		editable = view_edit_wing.getText();
		if (editable == null)
			return null;
		
		String wing = editable.toString();
		
		editable = view_edit_room.getText();
		if (editable == null)
			return null;
		
		String room = editable.toString();
		
		
		if ((building == null) || (floor == null) || (wing == null))
			return null;
		
		if ((building.length() == 0) || (floor.length() == 0) 
			|| (wing.length() == 0))
		{
			return null;
		}
		
		if (room != null)
			if (room.length() == 0)
				room = null;
		
		Log.d(TAG, "profile: b = "+building+", f = "+floor+", w = "+wing
			+", r = "+room);
		
		ScanProfile profile = new ScanProfile(building, floor, wing, room);
		
		return profile;
	}

	private void toastAlert(String text)
	{
		Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
	}

	private void enableTablePositions()
	{
		for (int id : this.view_table_items_ids)
		{
			TextView item = (TextView) findViewById(id);
			item.setClickable(true);
			item.setOnClickListener(listener_table_item);
			
			this.table_item_disabled_color = item.getCurrentTextColor();
			item.setTextColor(
				getResources().getColor(R.color.mapper_cell_active));
		}
	}

	private void disableTablePositions()
	{
		for (int id : this.view_table_items_ids)
		{
			TextView item = (TextView) findViewById(id);
			item.setClickable(false);
			item.setTextColor(this.table_item_disabled_color);
		}
	}
	
	
	private void doScanResultsHandling()
	{
		if (this.scan_results == null)
			return;
		
		if (this.scan_results.size() == 0)
		{
			// no results
			return;
		}
		
		unregisterReceiver(receiver_results);
		
		ArrayAdapter<String> results_adapter = 
			new ArrayAdapter<String>(getApplicationContext(), 
				R.layout.rfbul_list_item);
		
		String position = getTableItemPosition(mapper_scanning_item);
		
		for (ScanResult r : this.scan_results)
		{
			if (r.SSID.equalsIgnoreCase(SSID_TO_LOOK_FOR) == false)
				continue;
			
			String str = "(" + position + ") " 
				+ r.SSID + ": " + r.BSSID + ", " + r.level;
			
			results_adapter.add(str);
		}
		
		ListView lv = (ListView) findViewById(R.id.layout_mapper_list_results);
		lv.setAdapter(results_adapter);
		
		TextView table_item_view = 
			(TextView) findViewById(view_table_items_ids[mapper_scanning_item]);
		table_item_view.setTextColor(
			getResources().getColor(R.color.mapper_cell_scanned));
		
		insertResultsIntoDatabase();
		
		this.mapper_is_scanning = false;
	}


	private void insertResultsIntoDatabase()
	{
		MapperDatabaseAdapter db_adapter = 
			MapperDatabaseAdapter.getInstance(context);

		String building = this.scan_profile.getBuilding();
		String floor = this.scan_profile.getFloor();
		String wing = this.scan_profile.getWing();
		String room = this.scan_profile.getRoom();
		
		String table_item_position =
			getTableItemPosition(this.mapper_scanning_item);
		
		for (ScanResult r : this.scan_results)
		{
			if (r.SSID.equalsIgnoreCase(SSID_TO_LOOK_FOR) == false)
				continue;

			String ssid = r.SSID;
			String mac = r.BSSID;
			int signal = r.level;
			
			Log.d(TAG, "Adding entry: b = "+building+", f = "+ floor
				+ ", w = "+wing+", r = "+room);
			db_adapter.addEntry(building, floor, wing, room, ssid, mac, signal, 
				table_item_position);
		}
		
	}

	private String getTableItemPosition(int table_position)
	{
		if ((table_position < 0) || 
			(table_position > this.view_table_items_positions.length))
		{
			return "Unknown";
		}
		
		return this.view_table_items_positions[table_position];
	}


	class ScanProfile
	{
		String building;
		String floor;
		String wing;
		String room;
		
		public ScanProfile(String building, String floor, 
			String wing, String room)
		{
			this.building = building;
			this.floor = floor;
			this.wing = wing;
			this.room = room;
		}
		
		public boolean isHall()
		{
			return (this.room == null ? true : false);
		}
		
		public boolean isRoom()
		{
			return (this.room != null ? true : false);
		}
		
		public String getBuilding()
		{
			return this.building;
		}
		
		public String getFloor()
		{
			return this.floor;
		}
		
		public String getWing()
		{
			return this.wing;
		}
		
		public String getRoom()
		{
			String ret = "";
			if (isRoom())
				ret = this.room;
			return ret;
		}
	}

}
